<div class="tmd-doc">
<h1 class="tmd-header-1">
Atomic Operations Provided in The <code class="tmd-code-span">sync/atomic</code> Standard Package
</h1>
<p></p>
<div class="tmd-usual">
Atomic operations are more primitive than other synchronization techniques. They are lockless and generally implemented directly at hardware level. In fact, they are often used in implementing other synchronization techniques.
</div>
<p></p>
<div class="tmd-usual">
Please note, many examples below are not concurrent programs. They are just for demonstration and explanation purposes, to show how to use the atomic functions provided in the <code class="tmd-code-span">sync/atomic</code> standard package.
</div>
<p></p>
<h3 id="overview" class="tmd-header-3">
Overview of Atomic Operations Provided Before Go 1.19-
</h3>
<p></p>
<div class="tmd-usual">
The <code class="tmd-code-span">sync/atomic</code> standard package provides the following five atomic functions for an integer type <code class="tmd-code-span">T</code>, where <code class="tmd-code-span">T</code> must be any of <code class="tmd-code-span">int32</code>, <code class="tmd-code-span">int64</code>, <code class="tmd-code-span">uint32</code>, <code class="tmd-code-span">uint64</code> and <code class="tmd-code-span">uintptr</code>.
</div>
<p></p>
<pre class="tmd-code line-numbers must-line-numbers">
<code class="language-go">func AddT(addr *T, delta T)(new T)
func LoadT(addr *T) (val T)
func StoreT(addr *T, val T)
func SwapT(addr *T, new T) (old T)
func CompareAndSwapT(addr *T, old, new T) (swapped bool)
</code></pre>
<p></p>
<div class="tmd-usual">
For example, the following five functions are provided for type <code class="tmd-code-span">int32</code>.
</div>
<pre class="tmd-code line-numbers must-line-numbers">
<code class="language-go">func AddInt32(addr *int32, delta int32)(new int32)
func LoadInt32(addr *int32) (val int32)
func StoreInt32(addr *int32, val int32)
func SwapInt32(addr *int32, new int32) (old int32)
func CompareAndSwapInt32(addr *int32,
				old, new int32) (swapped bool)
</code></pre>
<p></p>
<div class="tmd-usual">
The following four atomic functions are provided for (safe) pointer types. When these functions were introduced into the standard library, Go didn't support custom generics, so these functions are implemented through the <span class="tmd-broken-link">unsafe pointer type</span> <code class="tmd-code-span">unsafe.Pointer</code> (the Go counterpart of C <code class="tmd-code-span">void*</code>).
</div>
<pre class="tmd-code line-numbers must-line-numbers">
<code class="language-go">func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer)
func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer)
func SwapPointer(addr *unsafe.Pointer, new unsafe.Pointer,
				) (old unsafe.Pointer)
func CompareAndSwapPointer(addr *unsafe.Pointer,
				old, new unsafe.Pointer) (swapped bool)
</code></pre>
<p></p>
<div class="tmd-usual">
There is not an <code class="tmd-code-span">AddPointer</code> function for pointers, as Go (safe) pointers don't support arithmetic operations.
</div>
<p></p>
<div class="tmd-usual">
The <code class="tmd-code-span">sync/atomic</code> standard package also provides a type <code class="tmd-code-span">Value</code>, which corresponding pointer type <code class="tmd-code-span">*Value</code> has four methods (listed below, the later two were introduced by Go 1.17). We may use these methods to do atomic operations for values of any type.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">func (*Value) Load() (x interface{})
func (*Value) Store(x interface{})
func (*Value) Swap(new interface{}) (old interface{})
func (*Value) CompareAndSwap(old, new interface{}) (swapped bool)
</code></pre>
<p></p>
<h3 id="overview-1.19" class="tmd-header-3">
Overview of New Atomic Operations Provided Since Go 1.19
</h3>
<p></p>
<div class="tmd-usual">
Go 1.19 introduced several types, each of which owns a set of atomic operation methods, to achieve the same effects made by the package-level functions listed in the last section.
</div>
<p></p>
<div class="tmd-usual">
Among these types, <code class="tmd-code-span">Int32</code>, <code class="tmd-code-span">Int64</code>, <code class="tmd-code-span">Uint32</code>, <code class="tmd-code-span">Uint64</code> and <code class="tmd-code-span">Uintptr</code> are for integer atomic operations. The methods of the <code class="tmd-code-span">atomic.Int32</code> type are listed below. The methods of the other four types present in the similar way.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">func (*Int32) Add(delta int32) (new int32)
func (*Int32) Load() int32
func (*Int32) Store(val int32)
func (*Int32) Swap(new int32) (old int32)
func (*Int32) CompareAndSwap(old, new int32) (swapped bool)
</code></pre>
<p></p>
<div class="tmd-usual">
Since Go 1.18, Go has already supported custom generics. And some standard packages started to adopt custom generics since Go 1.19. The <code class="tmd-code-span">sync/atomic</code> package is one of these packages. The <code class="tmd-code-span">Pointer[T any]</code> type introduced in this package by Go 1.19 is a generic type. Its methods are listed below.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">(*Pointer[T]) Load() *T
(*Pointer[T]) Store(val *T)
(*Pointer[T]) Swap(new *T) (old *T)
(*Pointer[T]) CompareAndSwap(old, new *T) (swapped bool)
</code></pre>
<p></p>
<div class="tmd-usual">
Go 1.19 also introduced a <code class="tmd-code-span">Bool</code> type to do boolean atomic operations.
</div>
<p></p>
<h3 id="integer" class="tmd-header-3">
Atomic Operations for Integers
</h3>
<p></p>
<div class="tmd-usual">
The remaining of this article shows some examples on how to use the atomic operations provided in Go.
</div>
<p></p>
<div class="tmd-usual">
The following example shows how to do the <code class="tmd-code-span">Add</code> atomic operation on an <code class="tmd-code-span">int32</code> value by using the <code class="tmd-code-span">AddInt32</code> function. In this example, 1000 new concurrent goroutines are created by the main goroutine. Each of the new created goroutine increases the integer <code class="tmd-code-span">n</code> by one. Atomic operations guarantee that there are no data races among these goroutines. In the end, <code class="tmd-code-span">1000</code> is guaranteed to be printed.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import (
	"fmt"
	"sync"
	"sync/atomic"
)

func main() {
	var n int32
	var wg sync.WaitGroup
	for i := 0; i &lt; 1000; i++ {
		wg.Add(1)
		go func() {
			atomic.AddInt32(&amp;n, 1)
			wg.Done()
		}()
	}
	wg.Wait()

	fmt.Println(atomic.LoadInt32(&amp;n)) // 1000
}
</code></pre>
<p></p>
<div class="tmd-usual">
If the statement <code class="tmd-code-span">atomic.AddInt32(&amp;n, 1)</code> is replaced with <code class="tmd-code-span">n++</code>, then the output might be not <code class="tmd-code-span">1000</code>.
</div>
<p></p>
<div class="tmd-usual">
The following code re-implements the above program by using the <code class="tmd-code-span">atomic.Int32</code> type and its methods (since Go 1.19). This code looks a bit tidier.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import (
	"fmt"
	"sync"
	"sync/atomic"
)

func main() {
	var n atomic.Int32
	var wg sync.WaitGroup
	for i := 0; i &lt; 1000; i++ {
		wg.Add(1)
		go func() {
			n.Add(1)
			wg.Done()
		}()
	}
	wg.Wait()

	fmt.Println(n.Load()) // 1000
}
</code></pre>
<p></p>
<div class="tmd-usual">
The <code class="tmd-code-span">StoreT</code> and <code class="tmd-code-span">LoadT</code> atomic functions/methods are often used to implement the setter and getter methods of (the corresponding pointer type of) a type if the values of the type need to be used concurrently. For example, the function version:
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">type Page struct {
	views uint32
}

func (page *Page) SetViews(n uint32) {
	atomic.StoreUint32(&amp;page.views, n)
}

func (page *Page) Views() uint32 {
	return atomic.LoadUint32(&amp;page.views)
}
</code></pre>
<p></p>
<div class="tmd-usual">
And the type+methods version (since Go 1.19):
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">type Page struct {
	views atomic.Uint32
}

func (page *Page) SetViews(n uint32) {
	page.views.Store(n)
}

func (page *Page) Views() uint32 {
	return page.views.Load()
}
</code></pre>
<p></p>
<div class="tmd-usual">
For a signed integer type <code class="tmd-code-span">T</code> (<code class="tmd-code-span">int32</code> or <code class="tmd-code-span">int64</code>), the second argument for a call to the <code class="tmd-code-span">AddT</code> function can be a negative value, to do an atomic decrease operation. But how to do atomic decrease operations for values of an unsigned type <code class="tmd-code-span">T</code>, such as <code class="tmd-code-span">uint32</code>, <code class="tmd-code-span">uint64</code> and <code class="tmd-code-span">uintptr</code>? There are two circumstances for the second unsigned arguments.
</div>
<ol class="tmd-list">
<li class="tmd-list-item">
<div class="tmd-usual">
For an unsigned variable <code class="tmd-code-span">v</code> of type <code class="tmd-code-span">T</code>, <code class="tmd-code-span">-v</code> is legal in Go. So we can just pass <code class="tmd-code-span">-v</code> as the second argument of an <code class="tmd-code-span">AddT</code> call.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
For a positive constant integer <code class="tmd-code-span">c</code>, <code class="tmd-code-span">-c</code> is illegal to be used as the second argument of an <code class="tmd-code-span">AddT</code> call (where <code class="tmd-code-span">T</code> denotes an unsigned integer type). We can used <code class="tmd-code-span">^T(c-1)</code> as the second argument instead.
</div>
</li>
</ol>
<p></p>
<div class="tmd-usual">
This <code class="tmd-code-span">^T(v-1)</code> trick also works for an unsigned variable <code class="tmd-code-span">v</code>, but <code class="tmd-code-span">^T(v-1)</code> is less efficient than <code class="tmd-code-span">T(-v)</code>.
</div>
<p></p>
<div class="tmd-usual">
In the trick <code class="tmd-code-span">^T(c-1)</code>, if <code class="tmd-code-span">c</code> is a typed value and its type is exactly <code class="tmd-code-span">T</code>, then the form can shortened as <code class="tmd-code-span">^(c-1)</code>.
</div>
<p></p>
<div class="tmd-usual">
Example:
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import (
	"fmt"
	"sync/atomic"
)

func main() {
	var (
		n uint64 = 97
		m uint64 = 1
		k int    = 2
	)
	const (
		a        = 3
		b uint64 = 4
		c uint32 = 5
		d int    = 6
	)

	show := fmt.Println
	atomic.AddUint64(&amp;n, -m)
	show(n) // 96 (97 - 1)
	atomic.AddUint64(&amp;n, -uint64(k))
	show(n) // 94 (96 - 2)
	atomic.AddUint64(&amp;n, ^uint64(a - 1))
	show(n) // 91 (94 - 3)
	atomic.AddUint64(&amp;n, ^(b - 1))
	show(n) // 87 (91 - 4)
	atomic.AddUint64(&amp;n, ^uint64(c - 1))
	show(n) // 82 (87 - 5)
	atomic.AddUint64(&amp;n, ^uint64(d - 1))
	show(n) // 76 (82 - 6)
	x := b; atomic.AddUint64(&amp;n, -x)
	show(n) // 72 (76 - 4)
	atomic.AddUint64(&amp;n, ^(m - 1))
	show(n) // 71 (72 - 1)
	atomic.AddUint64(&amp;n, ^uint64(k - 1))
	show(n) // 69 (71 - 2)
}
</code></pre>
<p></p>
<div class="tmd-usual">
A <code class="tmd-code-span">SwapT</code> function call is like a <code class="tmd-code-span">StoreT</code> function call, but returns the old value.
</div>
<p></p>
<div class="tmd-usual">
A <code class="tmd-code-span">CompareAndSwapT</code> function call only applies the store operation when the current value matches the passed old value. The <code class="tmd-code-span">bool</code> return result of the <code class="tmd-code-span">CompareAndSwapT</code> function call indicates whether or not the store operation is applied.
</div>
<p></p>
<div class="tmd-usual">
Example:
</div>
<pre class="tmd-code line-numbers must-line-numbers">
<code class="language-go">package main

import (
	"fmt"
	"sync/atomic"
)

func main() {
	var n int64 = 123
	var old = atomic.SwapInt64(&amp;n, 789)
	fmt.Println(n, old) // 789 123
	swapped := atomic.CompareAndSwapInt64(&amp;n, 123, 456)
	fmt.Println(swapped) // false
	fmt.Println(n)       // 789
	swapped = atomic.CompareAndSwapInt64(&amp;n, 789, 456)
	fmt.Println(swapped) // true
	fmt.Println(n)       // 456
}
</code></pre>
<p></p>
<div class="tmd-usual">
The following is the corresponding type+methods version (since Go 1.19):
</div>
<p></p>
<pre class="tmd-code line-numbers must-line-numbers">
<code class="language-go">package main

import (
	"fmt"
	"sync/atomic"
)

func main() {
	var n atomic.Int64
	n.Store(123)
	var old = n.Swap(789)
	fmt.Println(n.Load(), old) // 789 123
	swapped := n.CompareAndSwap(123, 456)
	fmt.Println(swapped)  // false
	fmt.Println(n.Load()) // 789
	swapped = n.CompareAndSwap(789, 456)
	fmt.Println(swapped)  // true
	fmt.Println(n.Load()) // 456
}
</code></pre>
<p></p>
<div class="tmd-usual">
Please note, up to now (Go 1.25), atomic operations for 64-bit words, a.k.a. int64 and uint64 values, require the 64-bit words must be 8-byte aligned in memory. For Go 1.19 introduced atomic method operations, this requirement is always satisfied, either on 32-bit or 64-bit architectures, but this is not true for atomic function operations on 32-bit architectures. Please read <a href="memory-layout.html">memory layout</a> for details.
</div>
<p></p>
<p></p>
<h3 id="pointer" class="tmd-header-3">
Atomic Operations for Pointers
</h3>
<p></p>
<div class="tmd-usual">
Above has mentioned that there are four functions provided in the <code class="tmd-code-span">sync/atomic</code> standard package to do atomic pointer operations, with the help of unsafe pointers.
</div>
<p></p>
<div class="tmd-usual">
From the article <a href="unsafe.html">type-unsafe pointers</a>, we learn that, in Go, values of any pointer type can be explicitly converted to <code class="tmd-code-span">unsafe.Pointer</code>, and vice versa. So values of <code class="tmd-code-span">*unsafe.Pointer</code> type can also be explicitly converted to <code class="tmd-code-span">unsafe.Pointer</code>, and vice versa.
</div>
<p></p>
<p></p>
<div class="tmd-usual">
The following example is not a concurrent program. It just shows how to do atomic pointer operations. In this example, <code class="tmd-code-span">T</code> can be an arbitrary type.
</div>
<pre class="tmd-code line-numbers must-line-numbers">
<code class="language-go">package main

import (
	"fmt"
	"sync/atomic"
	"unsafe"
)

type T struct {x int}

func main() {
	var pT *T
	var unsafePPT = (*unsafe.Pointer)(unsafe.Pointer(&amp;pT))
	var ta, tb = T{1}, T{2}
	// store
	atomic.StorePointer(
		unsafePPT, unsafe.Pointer(&amp;ta))
	fmt.Println(pT) // &amp;{1}
	// load
	pa1 := (*T)(atomic.LoadPointer(unsafePPT))
	fmt.Println(pa1 == &amp;ta) // true
	// swap
	pa2 := atomic.SwapPointer(
		unsafePPT, unsafe.Pointer(&amp;tb))
	fmt.Println((*T)(pa2) == &amp;ta) // true
	fmt.Println(pT) // &amp;{2}
	// compare and swap
	b := atomic.CompareAndSwapPointer(
		unsafePPT, pa2, unsafe.Pointer(&amp;tb))
	fmt.Println(b) // false
	b = atomic.CompareAndSwapPointer(
		unsafePPT, unsafe.Pointer(&amp;tb), pa2)
	fmt.Println(b) // true
}
</code></pre>
<p></p>
<div class="tmd-usual">
Yes, it is quite verbose to use the pointer atomic functions. In fact, not only are the uses verbose, they are also not protected by <a href="https://golang.org/doc/go1compat">Go 1 compatibility guidelines</a>, for these uses require to import the <code class="tmd-code-span">unsafe</code> standard package.
</div>
<p></p>
<p></p>
<p></p>
<div class="tmd-usual">
On the contrary, the code will be much simpler and cleaner if we use the Go 1.19 introduced generic <code class="tmd-code-span">Pointer</code> type and its methods to do atomic pointer operations, as the following code shows.
</div>
<p></p>
<pre class="tmd-code line-numbers must-line-numbers">
<code class="language-go">package main

import (
	"fmt"
	"sync/atomic"
)

type T struct {x int}

func main() {
	var pT atomic.Pointer[T]
	var ta, tb = T{1}, T{2}
	// store
	pT.Store(&amp;ta)
	fmt.Println(pT.Load()) // &amp;{1}
	// load
	pa1 := pT.Load()
	fmt.Println(pa1 == &amp;ta) // true
	// swap
	pa2 := pT.Swap(&amp;tb)
	fmt.Println(pa2 == &amp;ta) // true
	fmt.Println(pT.Load())  // &amp;{2}
	// compare and swap
	b := pT.CompareAndSwap(&amp;ta, &amp;tb)
	fmt.Println(b) // false
	b = pT.CompareAndSwap(&amp;tb, &amp;ta)
	fmt.Println(b) // true
}
</code></pre>
<p></p>
<div class="tmd-usual">
More importantly, the implementation using the generic <code class="tmd-code-span">Pointer</code> type is protected by Go 1 compatibility guidelines.
</div>
<p></p>
<h3 id="arbitrary" class="tmd-header-3">
Atomic Operations for Values of Arbitrary Types
</h3>
<p></p>
<div class="tmd-usual">
The <code class="tmd-code-span">Value</code> type provided in the <code class="tmd-code-span">sync/atomic</code> standard package can be used to atomically load and store values of any type.
</div>
<p></p>
<div class="tmd-usual">
Type <code class="tmd-code-span">*Value</code> has several methods: <code class="tmd-code-span">Load</code>, <code class="tmd-code-span">Store</code>, <code class="tmd-code-span">Swap</code> and <code class="tmd-code-span">CompareAndSwap</code> (The latter two are introduced in Go 1.17). The input parameter types of these methods are all <code class="tmd-code-span">interface{}</code>. So any value may be passed to the calls to these methods. But for an addressable <code class="tmd-code-span">Value</code> value <code class="tmd-code-span">v</code>, once the <code class="tmd-code-span">v.Store()</code> (a shorthand of <code class="tmd-code-span">(&amp;v).Store()</code>) call has ever been called, then the subsequent method calls on value <code class="tmd-code-span">v</code> must also take argument values with the same <a href="type-system-overview.html#concrete-type">concrete type</a> as the argument of the first <code class="tmd-code-span">v.Store()</code> call, otherwise, panics will occur. A <code class="tmd-code-span">nil</code> interface argument will also make the <code class="tmd-code-span">v.Store()</code> call panic.
</div>
<p></p>
<p></p>
<div class="tmd-usual">
An example:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import (
	"fmt"
	"sync/atomic"
)

func main() {
	type T struct {a, b, c int}
	var ta = T{1, 2, 3}
	var v atomic.Value
	v.Store(ta)
	var tb = v.Load().(T)
	fmt.Println(tb)       // {1 2 3}
	fmt.Println(ta == tb) // true

	v.Store("hello") // will panic
}
</code></pre>
<p></p>
<div class="tmd-usual">
Another example (for Go 1.17+):
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import (
	"fmt"
	"sync/atomic"
)

func main() {
	type T struct {a, b, c int}
	var x = T{1, 2, 3}
	var y = T{4, 5, 6}
	var z = T{7, 8, 9}
	var v atomic.Value
	v.Store(x)
	fmt.Println(v) // {{1 2 3}}
	old := v.Swap(y)
	fmt.Println(v)       // {{4 5 6}}
	fmt.Println(old.(T)) // {1 2 3}
	swapped := v.CompareAndSwap(x, z)
	fmt.Println(swapped, v) // false {{4 5 6}}
	swapped = v.CompareAndSwap(y, z)
	fmt.Println(swapped, v) // true {{7 8 9}}
}
</code></pre>
<p></p>
<div class="tmd-usual">
In fact, we can also use the atomic pointer functions explained in the last section to do atomic operations for values of any type, with one more level indirection. Both ways have their respective advantages and disadvantages. Which way should be used depends on the requirements in practice.
</div>
<p></p>
<h3 class="tmd-header-3">
Memory Order Guarantee Made by Atomic Operations in Go
</h3>
<p></p>
<div class="tmd-usual">
Please read <a href="memory-model.html#atomic">Go memory model</a> for details.
</div>
<p></p>
<p></p>
</div>
